/*
 * 二维数组回形遍历
 *
 * 题目链接：https://programming.pku.edu.cn/probset/c64f419547984d8ca5779180c6354146/b962d6ada3d14301870bb9cb5bdb716b/
 * 作者：lyazj <seeson@pku.edu.cn>
 *
 * 本题所需主要知识点：
 *   - 数组
 *   - 循环
 */

#include <iostream>

using namespace std;

int main()
{
  int m, n;
  cin >> m >> n;

  // 注意 a 定义在 m 和 n 初始化之后
  int a[m][n];

  // 输入
  for(int i = 0; i < m; ++i) {
    for(int j = 0; j < n; ++j) {
      cin >> a[i][j];
    }
  }

  // 四种移动方向
  int d[4][2] = {
    { 0,  1},
    { 1,  0},
    { 0, -1},
    {-1,  0},
  };

  // 四种边界变化
  int db[4][4] = {
    { 1,  0,  0,  0},
    { 0,  0,  0, -1},
    { 0, -1,  0,  0},
    { 0,  0,  1,  0},
  };

  // 当前状态：剩余范围，方向，位置
  int xf = 0, xl = m - 1, yf = 0, yl = n - 1, s = 0, x = 0, y = 0;

  // 主循环
  while(xf <= xl || yf <= yl) {
    // 沿二维区域边界前行，方向为 d[s]
    while(x >= xf && x <= xl && y >= yf && y <= yl) {
      cout << a[x][y] << endl;
      x += d[s][0], y += d[s][1];
    }
    // 遇到边界，回退，更新边界、方向和位置
    x -= d[s][0], y -= d[s][1];
    xf += db[s][0], xl += db[s][1], yf += db[s][2], yl += db[s][3];
    if(++s == 4) s = 0;
    x += d[s][0], y += d[s][1];
  }

  return 0;
}
